#ifndef GAME_H
#define GAME_H

#include "Singleton.h"

#include <QDebug>
#include <QList>
#include <QMap>
#include <exception>

class IteratorOutOfBounds: public std::exception {
public:
    IteratorOutOfBounds()
        :std::exception(){}
    const char* what(){
        return "IteratorOutOfBounds";
    }
};

template <class Item>
class List {
  public:
    List(long size=10){
        _size = size;
        _list = new int[size];
    }
    virtual ~List(){ delete _list; }
    int Count() const{ return _size; }
    Item Get(long index) const{ return _list[index]; }
    void Set(long index, int v){ _list[index] = v; }

private:
    long _size;
    int* _list;
};

template <class Item>
class Iterator {
  public:
    virtual void First() = 0;
    virtual void Next() = 0;
    virtual bool IsDone() const = 0;
    virtual Item CurrentItem() const = 0;
    virtual ~Iterator(){}
protected:
    Iterator(){}
};

template <class Item>
class ListIterator: public Iterator<Item> {
public:
    ListIterator(const List<Item>* aList)
        : _list(aList),_current(0)
        { }
    virtual ~ListIterator(){}
    virtual void First() { _current = 0; }
    virtual void Next() { _current++; }
    virtual bool IsDone() const { return _current >= _list->Count(); }
    virtual Item CurrentItem() const {
        if(IsDone()) throw IteratorOutOfBounds();
        return _list->Get(_current);
    }
private:
    const List<Item>* _list;
    long _current;
};

template <class Item>
class IteratorPtr {
public:
    IteratorPtr(Iterator<Item>* i):_i(i){}
    virtual ~IteratorPtr(){ delete _i; }
    Iterator<Item>* operator ->(){ return _i; }
    Iterator<Item>& operator *(){ return *_i; }

private:
    IteratorPtr(const IteratorPtr&){}
    IteratorPtr& operator =(const IteratorPtr&){}
private:
    Iterator<Item>* _i;
};



#endif // GAME_H
